package com.netease.nie.service;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.netease.nie.base.cache.redis.Redis;
import com.netease.nie.common.CommonService;
import com.netease.nie.constants.CachePrefixConstants;
import com.netease.nie.dao.DrawLotteryNormalGoodsInfoDao;
import com.netease.nie.dao.DrawLotteryPrizeTimeLineDao;
import com.netease.nie.model.DrawLotteryNormalGoodsInfo;
import com.netease.nie.model.DrawLotteryPrizeTimeLine;

/**
 * 抽奖商品业务服务接口实现
 * @author gzlibingjie
 */
@Service
public class DrawLotteryNormalGoodsInfoServiceImpl extends CommonService implements DrawLotteryNormalGoodsInfoService {

	@Resource
	DrawLotteryNormalGoodsInfoDao drawLotteryNormalGoodsInfoDao;
	
	@Resource
	DrawLotteryPrizeTimeLineDao drawLotteryPrizeTimeLineDao;
	
	@Autowired
	private Redis redis;
	
	private static final String DRAW_LOTTERY_NORMAL_GOODS_INFO_PREFIX = CachePrefixConstants.DrawLotteryPrefix.DRAW_LOTTERY_NORMAL_GOODS_INFO_PREFIX;
	
	/**
	 * 获取指定抽奖活动下的抽奖商品列表
	 * @param activityId 抽奖活动ID
	 * @return 抽奖商品列表
	 */
	@Override
	public List<DrawLotteryNormalGoodsInfo> listByActivityId(Integer activityId) {
		if (activityId == null) {
			return null;
		}
		String nomralGoodsKey = DRAW_LOTTERY_NORMAL_GOODS_INFO_PREFIX + activityId;
		List<DrawLotteryNormalGoodsInfo> normalGoodsInfoList = null;
		if (redis.exists(nomralGoodsKey)) {
			normalGoodsInfoList = redis.lrange(nomralGoodsKey, 0, -1, DrawLotteryNormalGoodsInfo.class);
		} else {
			normalGoodsInfoList = drawLotteryNormalGoodsInfoDao.queryByActivityId(activityId);
			if (normalGoodsInfoList != null && !normalGoodsInfoList.isEmpty()) {
				redis.rpush(nomralGoodsKey, normalGoodsInfoList);
			}
		}
		return normalGoodsInfoList;
	}

	/**
	 * 根据ID获取抽奖商品信息
	 * @param id 抽奖活动ID
	 * @return 抽奖商品信息
	 */
	public DrawLotteryNormalGoodsInfo queryDrawLotteryNormalGoodsInfoById(int id) {
		return drawLotteryNormalGoodsInfoDao.queryDrawLotteryNormalGoodsInfoById(id);
	}

	/**
	 * 进行抽奖
	 * @param activityId 抽奖活动的唯一ID
	 * @return 抽中的普通奖品，未抽中返回null
	 * 备注：此方法要求严格的原子性，为避免过大地影响抽奖的性能，只对此方法作isolation = Isolation.SERIALIZABLE的限制，
	 *          但为了避免回滚时出错，故设置成不会捕获错误回滚，将回滚操作交给上层调用事务来处理
	 */
	@Override
	public DrawLotteryNormalGoodsInfo draw(Integer activityId) {
		DrawLotteryPrizeTimeLine currentTimeLine = drawLotteryPrizeTimeLineDao.queryLast(activityId);
		if (currentTimeLine == null) {    // 没有满足要求的时间线
			return null;
		}
		
		drawLotteryPrizeTimeLineDao.addPt(currentTimeLine.getId());    // 增加一次参加次数
		currentTimeLine = drawLotteryPrizeTimeLineDao.queryById(currentTimeLine.getId());    // 重新获取更新后的时间线数据
		
		// 判断是否中奖
		if (currentTimeLine.getCurrentPt() >= currentTimeLine.getMinPt()) {    // 满足参与人次
			drawLotteryPrizeTimeLineDao.subtractStock(currentTimeLine.getId());    // 中奖，消耗库存
			Integer id = currentTimeLine.getPrizeId();
			drawLotteryNormalGoodsInfoDao.deductStock(id);
			return drawLotteryNormalGoodsInfoDao.queryNotDeletedDrawLotteryNormalGoodsInfoById(id);
		}
		
		return null;
	}

	public Map<Integer, DrawLotteryNormalGoodsInfo> queryDrawLotteryNormalGoodsInfoMapByNormalGoodsIds(
			List<Integer> normalGoodsIds) {
		List<DrawLotteryNormalGoodsInfo> drawLotteryNormalGoodsInfoList = drawLotteryNormalGoodsInfoDao.queryDrawLotteryNormalGoodsInfosByNormalGoodsIds(normalGoodsIds);
		if (drawLotteryNormalGoodsInfoList != null && !drawLotteryNormalGoodsInfoList.isEmpty()) {
			Map<Integer, DrawLotteryNormalGoodsInfo> drawLotteryNormalGoodsInfoMap = new HashMap<Integer, DrawLotteryNormalGoodsInfo>();
			DrawLotteryNormalGoodsInfo drawLotteryNormalGoodsInfo = null;
			int drawLotteryNormalGoodsInfoListSize = drawLotteryNormalGoodsInfoList.size();
			for (int i = 0; i < drawLotteryNormalGoodsInfoListSize; i++) {
				drawLotteryNormalGoodsInfo = drawLotteryNormalGoodsInfoList.get(i);
				drawLotteryNormalGoodsInfoMap.put(drawLotteryNormalGoodsInfo.getId(), drawLotteryNormalGoodsInfo);
			}
			return drawLotteryNormalGoodsInfoMap;
		}
			
		return Collections.emptyMap();
	}

}
